package com.bang.study.day01;

import com.bang.study.util.ArrayUtil;
import com.bang.study.util.TestUtil;

/**
 * @Auther: Bang
 * @Date: 2019/9/21 0021 10:18
 * @Description: 选择排序
 * @描述:
 *      n个记录的直接选择排序可经过n-1趟直接选择排序得到有序结果。具体算法描述如下：
 *     1. 初始状态：无序区为R[1..n]，有序区为空；
 *     2. 第i趟排序(i=1,2,3…n-1)开始时，当前有序区和无序区分别为R[1..i-1]和R(i..n）。
 *        该趟排序从当前无序区中-选出关键字最小的记录 R[k]，将它与无序区的第1个记录R交换，
 *        使R[1..i]和R[i+1..n)分别变为记录个数增加1个的新有序区和记录个数减少1个的新无序区；
 *     3. n-1趟结束，数组有序化了。

 * @算法分析:
 *          最佳情况：T(n) = O(n)   最差情况：T(n) = O(n2)   平均情况：T(n) = O(n2)
 *          表现最稳定的排序算法之一，因为无论什么数据进去都是O(n2)的时间复杂度，
 *          所以用到它的时候，数据规模越小越好。唯一的好处: 不占用额外的内存空间
 *
 * @工作原理:
 *          首先在未排序序列中找到最小（大）元素，存放到排序序列的起始位置，
 *          然后，再从剩余未排序元素中继续寻找最小（大）元素，然后放到已排序序列的末尾。
 *          以此类推，直到所有元素均排序完毕。
 */
public class SelectionSort {

    /**
     * 对数组进行排序
     * @param arr
     */
    public static void sort(Integer[] arr) {
//        long startTime = System.nanoTime();
        int length = arr.length;
        for (int i = 0; i < length; i++) {
            int minIndex = i;
            for (int j = i + 1; j < arr.length; j++) {
                if (arr[j] < arr[minIndex]) {
                    minIndex = j;
                }
            }
            // 交换元素
            int temp = arr[i];
            arr[i] = arr[minIndex];
            arr[minIndex] = temp;
        }
//        long endTime = System.nanoTime();
//        double time = (endTime - startTime) / 1000000000.0;
//        System.err.println(String.format("SelectionSort消耗时间: %s S ,数据量: %s", time, length));
    }



    public static void main(String[] args) throws Exception {
        Integer[] integers = ArrayUtil.generateRandomArray(10000, 0, 100000);
        TestUtil.test(SelectionSort.class, integers);
        ArrayUtil.printArray(integers, 10);
    }

}
